package data;

import anaydis.sort.data.DataSetGenerator;
import org.jetbrains.annotations.NotNull;

import java.util.*;

/**
 * An�lisis y Dise�o de Algoritmos - Pr�ctica 2010
 * <p/>
 * String-typed implementation of {@link anaydis.sort.data.DataSetGenerator <T>}
 * <p/>
 * This implementation interanally uses a dictionary! Other implementations
 * (e.g. IntegerDataSetGenerator) should dinamically generate each List<T>
 */
public class StringDataSetGenerator implements DataSetGenerator<String> {
    private final List<String> dictionary;

    public StringDataSetGenerator() {
        dictionary = initDictionary();
    }

    @NotNull
    public List<String> createAscending(final int length) {
        if (length > dictionary.size()) {
            throw new IllegalArgumentException("Ojo! StringDataSetGenerator " +
                    "puede generar valores HASTA un length de " + dictionary.size());
        }

        final List<String> copy = new ArrayList<String>();

        copy.addAll(dictionary.subList(0, length));

        return copy;
    }

    /**
     * Hey!! {@link java.util.Collections#reverse(java.util.List)} SHOUL NOT BE USED ON
     * THE INTEGER IMPLEMENTATION! Why not?!
     */
    @NotNull
    public List<String> createDescending(int length) {
        final List<String> copy = createAscending(length);

        Collections.reverse(copy);

        return copy;
    }

    /**
     * Hey!! {@link java.util.Collections#shuffle(java.util.List)} SHOUL NOT BE USED ON
     * THE INTEGER IMPLEMENTATION! Why not?!
     */
    @NotNull
    public List<String> createRandom(int length) {
        final List<String> copy = createAscending(length);

        Collections.shuffle(copy);

        return copy;
    }

    @NotNull
    public Comparator<String> getComparator() {
        return STRING_COMPARATOR;
    }

    private List<String> initDictionary() {
        return Arrays.asList("ALICE", "AMANDA",
                "AMY", "ANDREA", "ANGELA", "ANN", "ANNA", "ANNE", "ANNIE",
                "ASHLEY", "BARBARA", "BETTY", "BEVERLY", "BONNIE", "BRENDA",
                "CARMEN", "CAROL", "CAROLYN", "CATHERINE", "CHERYL",
                "CHRISTINA", "CHRISTINE", "CINDY", "CONNIE", "CRYSTAL",
                "CYNTHIA", "DAWN", "DEBORAH", "DEBRA", "DENISE", "DIANA",
                "DIANE", "DONNA", "DORIS", "DOROTHY", "EDITH", "EDNA",
                "ELIZABETH", "EMILY", "EVELYN", "FLORENCE", "FRANCES",
                "GLADYS", "GLORIA", "GRACE", "HEATHER", "HELEN", "IRENE",
                "JACQUELINE", "JANE", "JANET", "JANICE", "JEAN", "JENNIFER",
                "JESSICA", "JOAN", "JOYCE", "JUDITH", "JUDY", "JULIA", "JULIE",
                "KAREN", "KATHERINE", "KATHLEEN", "KATHRYN", "KATHY", "KELLY",
                "KIM", "KIMBERLY", "LAURA", "LILLIAN", "LINDA", "LISA", "LOIS",
                "LORI", "LOUISE", "MARGARET", "MARIA", "MARIE", "MARILYN",
                "MARTHA", "MARY", "MELISSA", "MICHELLE", "MILDRED", "NANCY",
                "NICOLE", "NORMA", "PABLIUS", "PAMELA", "PATRICIA", "PAULA", "PEDRO",
                "PEGGY", "PHYLLIS", "RACHEL", "REBECCA", "RITA", "ROBIN", "ROSA",
                "ROSE", "RUBY", "RUTH", "SANDRA", "SARA", "SARAH", "SHARON", "SHIRLEY",
                "STEPHANIE", "SUSAN", "TAMMY", "TERESA", "THERESA", "TIFFANY",
                "TINA", "TRACY", "VICTORIA", "VIRGINIA", "WANDA", "WENDY");
    }

    /**
     * Private static final field to return always the same instance of Comparator<String>
     * upon {@link #getComparator()} invocation
     */
    private static final Comparator<String> STRING_COMPARATOR = new Comparator<String>() {

        public int compare(String a, String b) {
            return a.compareTo(b);
        }
    };
}